# coding=utf-8
# ☯ Author: ChinaPython
# ☯ Email : chinapython@yeah.net
# ☯ Date  : 2019-08-05 13:20
import PySimpleGUI as sg

# 1、地址码：1-6位
# 2、出生日期码：15位身份证：7-12位、18位：7-14位
# 3、序号码：15位身份证：13-15位、18位身份证：14-17位
# 4、性别码：15位身份证：15位、18位身份证：17位(单数位男，双数位女)
# 5、校验码：0123456789X


with open('code.ini', 'r', encoding='utf-8') as f:
    cities = eval('{' + f.read().replace('\n', '').replace(' ', '') + '}')


# 转换
def transform(id_code):
    try:
        # 转换17位
        code = id_code[:6] + '19' + id_code[6:12] + id_code[12:] if len(id_code) == 15 else id_code[:17]
        # 计算或获取校验位
        passport = code + str(
            {0: '1', 1: '0', 2: 'X',
             3: '9', 4: '8', 5: '7',
             6: '6', 7: '5', 8: '4',
             9: '3', 10: '2'}[sum(
                [int(code[0]) * 7, int(code[1]) * 9, int(code[2]) * 10,
                 int(code[3]) * 5, int(code[4]) * 8, int(code[5]) * 4,
                 int(code[6]) * 2, int(code[7]) * 1, int(code[8]) * 6,
                 int(code[9]) * 3, int(code[10]) * 7, int(code[11]) * 9,
                 int(code[12]) * 10, int(code[13]) * 5, int(code[14]) * 8,
                 int(code[15]) * 4, int(code[16]) * 2
                 ]) % 11])
        # 区域划分
        city = cities.get(int(passport[:6]))
        if city is None:
            city = cities.get(int(passport[:4] + '00'))
        if city is None:
            city = cities.get(int(passport[:2] + '0000'))
        city = ['', '', ''] if city is None else city.split(',')
        return {
            '原始代码': "'" + id_code,
            '代码类型': '老版证件' if len(id_code) == 15 else '新版证件',
            '身份证号': "'" + passport,
            '所属省级': city[0],
            '地级市区': city[1],
            '区县市级': city[2],
            '出生日期': "'" + passport[6:14],
            '证件序列': "'" + passport[14:17],
            '证件性别': '男' if int(passport[16:17]) % 2 == 1 else '女',
            '校验代码': passport[17:],
        }
    except Exception as e:
        return print(e)


# 保存
def save(file, items=None):
    file = ''.join(file.split('.')[:-1]) + '_解析.csv'
    if items is None:
        with open(file, 'a+', encoding='gb2312') as f:
            f.write(','.join([
                '原始代码', '代码类型', '身份证号', '所属省级', '地级市区',
                '区县市级', '出生日期', '证件序列', '证件性别', '校验代码'
            ]) + '\n')
        return file
    else:
        temps = [','.join(list(item.values())) + '\n' for item in items]
        with open(file, 'a+', encoding='gb2312') as f:
            f.write(''.join(temps))


# All the stuff inside your window. This is the PSG magic code compactor...
layout = [
    [
        sg.Input(
            do_not_clear=True,
            default_text='',
            text_color='red',
            key='file'
        ),
        sg.FileBrowse(button_text='载入', key='loading'),
        sg.Button(button_text='开始', key='start'),
        sg.Button(button_text='退出', key='logout')
    ],
    [sg.ProgressBar(100, orientation='h', size=(58, 10), key='progbar')]

]

# Create the Window
window = sg.Window('健康通公民身份证解析工具_高速', layout, icon='icon.ico')
progress_bar = window.FindElement('progbar')
# Event Loop to process "events"
while True:
    event, values = window.Read()
    # logout the system
    if event == 'start':
        progress_bar.UpdateBar(0)
        file, loading = values['file'], values['loading']
        if file != loading or len(loading) == 0:
            continue
        window.Element('file').Update('正在解析中.........')
        # create new file
        save(file)
        with open(file, 'r', encoding='utf-8') as f:
            lines = f.readlines()
        items = []
        for index in range(len(lines)):
            line = lines[index]
            if index == len(lines) - 1:
                progress_bar.UpdateBar(100)
            else:
                progress_bar.UpdateBar(int((index / len(lines)) * 100))
            id_temp = line.strip()
            if len(id_temp) != 15 and len(id_temp) != 18:
                continue
            item = transform(id_code=id_temp)
            if item is None:
                continue
            items.append(item)
            # save to csv file
        save(file, items)
        window.Element('file').Update('解析完毕........')
    if event == 'logout' or event is None:
        break
window.Close()

if __name__ == '__main__':
    pass
